﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;

namespace Kaiser.Extensions
{
    public static class EntityExtensions
    {
        /// <summary>
        /// 把list转换成数据表,
        ///  todo 这里如果属性是类，需要从类里面取一个字段作为值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entities"></param>
        /// <returns></returns>
        public static DataTable ToDataTable<T>(this IList<T> entities) where T : class
        {
            var dt = new DataTable();

            var properties = typeof(T).GetProperties().ToList();
            properties.ForEach(item =>
            {
                if (item.PropertyType.IsValueType)
                {
                    dt.Columns.Add(new DataColumn(item.Name) { DataType = item.PropertyType });
                }
                // todo 复杂类型的转换暂时不支持
                //else
                //{
                //    dr[property.Name] = GetValueByPropery(item, property.Name);
                //}
            });
            entities.ToList().ForEach(item =>
            {
                var dr = dt.NewRow();
                properties.ForEach(
                    property =>
                    {
                        if (property.PropertyType.IsValueType)
                        {
                            var value = property.GetValue(item, null); ;
                            dr[property.Name] = value;
                        }
                        //todo 复杂类型的转换暂时不支持
                        //else
                        //{
                        //    var fields = property.GetCustomAttributes(typeof(DataTableFieldAttribute), false);
                        //    if (fields.Length == 0) return;
                        //    dr[property.Name] = GetValueByPropery(item, ((DataTableFieldAttribute)fields[0]).ValueField);
                        //}
                    });
                dt.Rows.Add(dr);
            });
            return dt;
        }

        /// <summary>
        /// 把数据表转换成List
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static List<T> ToList<T>(this DataTable dt) where T : class,new()
        {
            var list = new List<T>();
            var plist = new List<PropertyInfo>(typeof(T).GetProperties());

            foreach (DataRow item in dt.Rows)
            {
                var s = Activator.CreateInstance<T>();
                foreach (DataColumn column in dt.Columns)
                {
                    var info = plist.Find(p => p.Name == column.ColumnName);
                    if (info == null) continue;
                    if (!Convert.IsDBNull(item[column.ColumnName]))
                    {
                        info.SetValue(s, item[column.ColumnName], null);
                    }
                }
                list.Add(s);
            }
            return list;
        }

        public static object GetValueByPropery<T>(this T entity, string propertyName) where T : class
        {
            var property = typeof(T).GetProperties().FirstOrDefault(item => item.Name == propertyName);
            if (property == null)
                return null;
            return property.GetValue(entity, null);
        }


        public static PropertyInfo GetProperyByName<T>(this T entity, string propertyName) where T : class
        {
            var property = typeof(T).GetProperties().FirstOrDefault(item => item.Name == propertyName);
            return property;
        }

        //public static DataTable PartialToDataTable<T>(this List<T> entities,List<string> properties,DataSet ds) where T : class {

        //    var dt = new DataTable();

        //    var propertyInfos= typeof(T).GetProperties().Where(item=>properties.Contains(item.Name)).ToList();
        //    propertyInfos.ForEach(item => dt.Columns.Add(new DataColumn(item.Name) { DataType = item.PropertyType }));
        //    entities.ForEach(item =>
        //    {
        //        var dr = dt.NewRow();
        //        propertyInfos.ForEach(
        //            property =>
        //            {
        //                var value = property.GetValue(item, null); ;
        //                dr[property.Name] = value;
        //            });
        //        dt.Rows.Add(dr);
        //    });
        //    return dt;
        //}

        //public static DataRow ToDataRow<T>(PropertyInfo[] infos) {

        //}

    }
}
